--- The final compiler pass
module frege.compiler.passes.Final where

import Data.TreeMap as TM(TreeMap, insert, each)
import Compiler.types.Global
import Compiler.enums.Flags
import Compiler.common.ImpExp
import Compiler.types.Symbols
import Compiler.types.External
import Compiler.Classtools as CT


buildMode :: Global -> Bool
buildMode g = isOn g.options.flags MAKE && isOff g.options.flags IDEMODE

clearTrees = changeST Global.{gen <- GenSt.{
                tTree = empty,
                rTree = empty,
                sTree = empty,
                xTree = empty,
                expSym = empty,
                consts = empty
            }}

{-- 
    This pass does only anything in build mode.
 
    For exported symbols, it sets the 'Symbol.expr' so that it appears
    like just imported from a class file.
    
    Any other expressions are removed.
    
    *Note:* This pass should be the last one, since it destroys the symbol table.   
-}        
cleanSymtab = do
        g <- getST
        when (buildMode g) do
            changeST Global.{packages <- insert g.thisPack (maptab g)}
            clearTrees  -- not needed anymore
        return ("symbol tables", 1)
    where
        maptab g = fmap symbol g.thisTab
            where
                symbol sym = case sym of
                    SymV{name} | Just e <- g.gen.expSym.lookup name
                           = sym.{expr = Just (exprFromA sarray eAarray eAarray.[e])}
                    SymV{} = sym.{expr = Nothing}
                    _ | sym.{env?} = sym.{env <- fmap symbol}
                      | otherwise  = sym
                swap :: (a,b) -> (b,a)
                swap (a,b) = (b,a)
                -- !kAarray = (arrayFromIndexList . map swap . each) empty -- g.gen.kTree
                !tAarray = (arrayFromIndexList . map swap . each) g.gen.tTree
                !rAarray = (arrayFromIndexList . map swap . each) g.gen.rTree
                !sAarray = (arrayFromIndexList . map swap . each) g.gen.sTree
                !eAarray = (arrayFromIndexList . map swap . each) g.gen.xTree
                karray = tAarray
                tarray = arrayCache rebuildTau tAarray.length
                rebuildTau n t  = tauFromA karray tAarray.[n] t
                rarray = arrayCache rebuildRho rAarray.length
                rebuildRho n t  = rhoFromA karray tarray sAarray rAarray.[n] t
                sarray = genericArrayMap (sigmaFromA karray tarray rarray) sAarray 
